#ifndef ARCH_TABLA_DISPERSION_H_
#define ARCH_TABLA_DISPERSION_H_

/********************************************************************
 * arch_tabla_dispersion.h
 * 
 * Descripcion :Esta clase representa un archivo de control para el hash
 * que almacena las entradas de la tabla de dispersion de formato [unsigned int] 
 * con organizacion secuencial, en bloques. Cada entrada de la tabla esta representada
 * por su posicion en el archivo.
*********************************************************************/

#include "arch_control.h"

class ArchTablaDispersion : public ArchControl {
	
	private:
	
		unsigned int size; //Contiene el tamanio de la tabla de dispersion
	
	public:
	
		ArchTablaDispersion(std::string& nombre, unsigned int tam_bloque);
	
		virtual ~ArchTablaDispersion();
		
		//IMPLEMENTO LOS METODOS DE ARCHIVO
		
		void crear() throw(ExcepCreandoArch);
		
		void abrir() throw(ExcepAbriendoArch);
		
		void append(unsigned int valor) throw(ExcepArchCerrado, ExcepEscribirBloque,ExcepLeerBloque);
		
		void borrar_ultimo();
		
		/* PARA SETEAR U OBTENER EL VALOR DE UNA ENTRADA DE LA TABLA,
		   USAR LAS PRIMITIVAS SET Y GET VALOR DE ARCH CONTROL. EL NRO DE
		   SLOT SERIA EL VALOR DE LA ENTRADA DE LA TABLA, Y EL VALOR
		   EL NRO DE BUCKET */
		
		/*
		 * Duplicar: Duplica la tabla de arch de dispersion, copiando de forma
		 * simetrica los valores de la mitad vieja de la tabla en la mitad nueva.
		 */	
		void duplicar() throw(ExcepArchCerrado, ExcepEscribirBloque,ExcepLeerBloque);
		
		/*
		 * Dividir: Si la tabla es simetrica la parte por la mitad, eliminando
		 * la mitad de la tabla del archivo y devuelve true. Sino devuelve false.
		 */
		bool dividir() throw(ExcepArchCerrado, ExcepEscribirBloque,ExcepLeerBloque);
		
		/*
		 * Actualizar circular: Actualiza todas las entradas de la tabla de dispersion
		 * circularmente desde la pos pasada como param hasta la misma pos, con el valor
		 * tmb pasado como param. Actualiza cada 'cant' de entradas.
		 */
		void actualizar_circular (unsigned int num_entrada, unsigned int cant, unsigned int valor)
									throw(ExcepArchCerrado, ExcepEscribirBloque,ExcepLeerBloque);
									
		/*
		 * Devuelve el tamanio de la tabla.
		 */
		 unsigned int get_size();
		 
		/*
 		 * Devuelve el tamanio libre del archivo en cantidad de bytes.
 		 */
 		unsigned int get_espacio_libre() throw(ExcepArchCerrado, ExcepLeerBloque);
 		
 		/*
 		 * Devuelve la cantidad de registros en el archivo.
 		 */
 		unsigned int get_cant_regs() throw(ExcepArchCerrado);

	private:
	
		/*
		 * Devuelve true si la tabla de dispersion es simetrica, false en caso contrario.
		 */
		bool es_simetrica();
		
		/*
		 * Devuelve el tamanio de la tabla, calculandolo desde el archivo.
		 */
		unsigned int get_size_desde_arch();
		
		/*
		 * Devuelve la cantidad de registros en el bloque pasado como param.
		 */
		unsigned int get_cant_regs_bloque(Bloque* bloque);
};

#endif
